package com.ho1ho.springboot.framework.core.auth;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class AuthenticationProviderImpl implements AuthenticationProvider {

	@Resource
	protected UserDetailsService userDetailsServiceImpl;

	@Resource
	protected BCryptPasswordEncoder bCryptPasswordEncoder;

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		String username = authentication.getName();
		String password = authentication.getCredentials().toString();

		log.debug("authenticate() username: {} password: {}", username, password);

		// If authentication successful, do not process userDetailsService in
		// WebSecurityConfig class.
		if (bCryptPasswordEncoder.matches(username, "$2a$10$wGrLy7IlkUG4C7hY2s1P2ejy/EEzMOLReGuMSfyzFvGokj.DVT71S")
				&& bCryptPasswordEncoder.matches(password, "$2a$10$KlNsLK/ajsmYZ.jM9AWwB.86VNBN0c3JgU2VxzdyOvFgzbVS7gTf.")) {
			List<GrantedAuthority> grantedAuths = new ArrayList<>();
			grantedAuths.add(new SimpleGrantedAuthority("ROLE_SUPER"));
			grantedAuths.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
			grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
			grantedAuths.add(new SimpleGrantedAuthority("ROLE_TEACHER"));
			grantedAuths.add(new SimpleGrantedAuthority("ROLE_STUDENT"));
			return new UsernamePasswordAuthenticationToken(username, password, grantedAuths);
		} else {
			// userDetailsServiceImpl.loadUserByUsernameAndPassword(username, password);
			// Authentication auth = new UsernamePasswordAuthenticationToken(username,
			// password, grantedAuthorities);
			// return auth;
			return null;
		}
	}

	@Override
	public boolean supports(Class<?> authentication) {
		log.debug("supports()");
		// https://blog.csdn.net/u013360850/article/details/78536736
		// return authentication.equals(UsernamePasswordAuthenticationToken.class);
		return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
	}

}
